package com.eonmind.pay.service.impl;

import com.eonmind.common.contract.data.response.ResponseEntity;
import com.eonmind.common.contract.timer.Timer;
import com.eonmind.common.provider.dto.VipDto;
import com.eonmind.common.provider.entity.pay.Cart;
import com.eonmind.common.provider.entity.pay.Order;
import com.eonmind.common.provider.entity.vip.VipPackage;
import com.eonmind.pay.PayApplication;
import com.eonmind.pay.config.WxPayConfig;
import com.eonmind.pay.dto.PayDto;
import com.eonmind.pay.entity.AliPay;
import com.eonmind.pay.entity.WxChatPay;
import com.eonmind.pay.enums.PayWayType;
import com.eonmind.pay.enums.TradeState;
import com.eonmind.pay.mapper.CartMapper;
import com.eonmind.pay.service.CartService;
import com.eonmind.pay.service.OrderService;
import com.eonmind.pay.service.PayService;
import com.eonmind.pay.service.PaymentInfoService;
import com.eonmind.pay.task.AsyncTasks;
import com.eonmind.pay.utils.HttpUtils;
import com.eonmind.pay.utils.WechatPay2ValidatorForRequest;
import com.eonmind.vip.contract.api.VipToPayFeignService;
import com.google.gson.Gson;

import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/**
 * @ClassName PayServiceImpl
 * @Description TODO
 * Author 32004
 * Date 2025/5/13 16:24
 * Version 1.0
 **/

@Slf4j
@Service
public class PayServiceImpl implements PayService {

    @Resource
    OrderService orderService;

    @Resource
    CartMapper cartMapper;

    @Resource
    WxPayConfig wxPayConfig;

    @Resource
    WxChatPay wxChatPay;

    @Resource
    PaymentInfoService paymentInfoService;

    @Resource
    VipToPayFeignService vipToPayFeignService;


    @Resource
    AsyncTasks asyncTasks;

    private static final ReentrantLock lock = new ReentrantLock();



    @Override
    public ResponseEntity<PayDto.PayCodeDto> payCode(Integer type, Long userId) {
        //1.查询当前购物车里的商品
        List<Cart> carts = cartMapper.selectList(userId);
        System.out.println(wxPayConfig.getDomain());


        StringBuilder description=new StringBuilder();
        //1.1计算总金额
        final double[] sum = {0};
        carts.forEach(cart->{
            sum[0] +=cart.getCount()*PayApplication.vipMap.get(cart.getProductId()).getCurrentPrice();
            description.append(cart.getCount()+"个"+PayApplication.vipMap.get(cart.getProductId()).getName()+",");

        });
        description.deleteCharAt(description.length()-1);
        String detail = description.toString();
        if(detail.getBytes(StandardCharsets.UTF_8).length>120){
            detail=detail.substring(0,30);
            detail=detail+"...";
        }

        sum[0]=sum[0]*100;
        //2.查找相同购物商品的未支付且未过期订单
        Order orderExist=orderService.findSameNoPayOrder(type,userId,sum[0],carts);
        //3.若存在，则直接返回二维码url
        if(orderExist!=null){
            //删除当前购物车商品
            asyncTasks.removeCarts(carts.stream().map(Cart::getProductId).toList(),userId);
            PayDto.PayCodeDto payCodeDto = new PayDto.PayCodeDto();
            payCodeDto.setCodeUrl(orderExist.getCodeUrl());
            payCodeDto.setOrderId(orderExist.getId().toString());
            payCodeDto.setAmount(orderExist.getAmount()/100.0);
            return ResponseEntity.success(orderExist.getCodeUrl(),payCodeDto);
        }
        //4.若不存在，则生成订单
        //4.1生成订单
        Order order=new Order();
        order.setUserId(userId);
        order.setStatus(TradeState.NOTPAY.getCode());
        order.setAmount((int) (sum[0]));
        order.setType(type);
        order.setCreateTime(Timer.currentTimestamp());
        order.setUpdateTime(Timer.currentTimestamp());
        order.setId(generateOrderId());
        order.setDescription(detail);
        //5.用户购物车商品绑定的订单号
        long begin=System.currentTimeMillis();
        asyncTasks.processUserCart(carts.stream().map(Cart::getId).toList(),order.getId(),userId);
        System.out.println("耗时："+(System.currentTimeMillis()-begin));
        String codeUrl="";

        //6.向微信支付发请求，生成二维码
        if(Objects.equals(type, PayWayType.WEIXIN.getCode())){

            try {
                codeUrl= wxChatPay.pay(order);


            } catch (IOException e) {
                return ResponseEntity.fail("生成支付二维码失败！");
            }
        }else{
            AliPay aliPay=new AliPay();
            codeUrl=aliPay.pay(order);
        }
        order.setCodeUrl(codeUrl);
        order.setCreateTime(Timer.currentTimestamp());
        order.setUpdateTime(Timer.currentTimestamp());
        order.setCodeUrl(codeUrl);
        PayDto.PayCodeDto payCodeDto = new PayDto.PayCodeDto();
        payCodeDto.setOrderId(order.getId().toString());
        payCodeDto.setCodeUrl(codeUrl);
        payCodeDto.setAmount(order.getAmount()/100.0);
        //7.保存订单
        orderService.save(order);
        return ResponseEntity.success("获取支付二维码成功！",payCodeDto);
    }

    @Override
    public String notifyOfWxPay(HttpServletRequest request, HttpServletResponse response) {
        com.google.gson.Gson gson = new Gson();
        String plainText="";
        //1.验签
        try {
             plainText= wxChatPay.notifyPay(request);
        } catch (GeneralSecurityException | IOException ex) {
            throw new RuntimeException(ex);
        }
        Map<String, String> resMap = new HashMap<>();
        //1.1失败应答
        if(plainText==null) {
            response.setStatus(500);
            log.info("通知验签失败");
            resMap.put("code", "ERROR");
            resMap.put("message", "通知验签失败");
            return gson.toJson(resMap);
        }
        //2.解析支付结果
        HashMap plainMap = gson.fromJson(plainText, HashMap.class);
            String orderNo = (String) plainMap.get("out_trade_no");

            //避免重入造成数据混乱
            if(lock.tryLock()){
                try {

                    Order order = orderService.getById(Long.parseLong(orderNo));
                    //处理重复通知
                    if(TradeState.NOTPAY.getCode().equals(order.getStatus())){
                        //更新订单状态
                        orderService.updateOrderStatusAndPayTime(Long.parseLong(orderNo), TradeState.SUCCESS.getCode(),
                                Timer.currentTimestamp());
                        this.addVipPrivilege(order.getId());

                        //记录支付日志
                        paymentInfoService.createPaymentInfo(plainText);
                    }


                } finally {
                    lock.unlock();
                }
            }
        //3.成功应答
        resMap.put("code", "SUCCESS");
        resMap.put("message", "成功");
        String resStr = gson.toJson(resMap);
        response.setStatus(200);
        return resStr;

    }

    @Override
    public ResponseEntity<Boolean> isPaySuccess(Long orderId) {
        boolean isPay=orderService.getPayStatus(orderId);
        return ResponseEntity.success(isPay);
    }

    @Override
    public void checkOrderStatus(Long id) {
        String jsonResult;
        try {
            jsonResult= wxChatPay.queryOrder(id.toString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        Gson gson = new Gson();
        HashMap resultMap = gson.fromJson(jsonResult, HashMap.class);

        //获取微信支付端的订单状态
        String tradeState = (String) resultMap.get("trade_state");
        //更新订单状态
        if(tradeState.equals(TradeState.SUCCESS.getType())){
            System.out.println(jsonResult);
            orderService.updateOrderStatusAndPayTime(id,TradeState.SUCCESS.getCode(),Timer.currentTimestamp());
            paymentInfoService.createPaymentInfo(jsonResult);
            this.addVipPrivilege(id);
        }else{
            try {
                wxChatPay.closeOrder(id.toString());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            orderService.updateOrderStatusAndPayTime(id,TradeState.CLOSED.getCode(),Timer.currentTimestamp());
        }
    }


    //订单号生成
    private Long generateOrderId() {
        // 获取当前时间戳（秒级）
        long timestamp = Timer.currentTimestamp() / 1000;
        // 生成一个 1 到 2025053166 之间的随机整数
        Random random = new Random();
        int randomInt = random.nextInt(2025053166) + 1;
        // 将时间戳左移 32 位，然后与随机整数进行按位或操作合并
        return (timestamp << 32) | randomInt;
    }


    //远程调用套餐服务获得权益
    private void addVipPrivilege(Long orderNo){
        List<Cart> carts = cartMapper.selectListByOrderId(orderNo);
        List<VipDto.PayToVipOrderSucDto> sucList = carts.stream().map(item -> {
            VipDto.PayToVipOrderSucDto suc = new VipDto.PayToVipOrderSucDto();
            suc.setPlanId(item.getProductId());
            suc.setUserId(item.getUserId());
            suc.setNum(item.getCount());
            suc.setPaymentId(orderNo);
            return suc;
        }).toList();
        ResponseEntity<Boolean> booleanResponseEntity = vipToPayFeignService.updateUserPlan(sucList);
    }




}
